Handling Dynamic Elements in Selenium
JustAcademy Selenium Training: JustAcademy Selenium Training Course
JustAcademy Demo Registration: Register for Selenium Course Demo
Handling Dynamic Elements is an important Selenium WebDriver skill because modern web applications frequently create, remove, update, or modify web elements while the application is running. Dynamic elements may change their attributes, text, location, visibility, enabled state, or DOM structure depending on user actions, AJAX responses, API calls, JavaScript execution, page navigation, or application state.
JustAcademy's Selenium curriculum includes handling dynamic elements together with implicit wait, explicit wait, FluentWait, page-load synchronization, and stable test execution strategies. Its related Selenium material also describes dynamic web elements as elements that can change because of user interaction or asynchronous data loading, with waits and advanced locators used to make automation more reliable. Selenium Training Course | Selenium Course Demo
1. What are Dynamic Elements?
Dynamic elements are web elements whose properties, location, content, availability, or existence can change during application execution. Unlike static elements, their HTML representation may not remain exactly the same between page loads or user interactions.
Static Element
↓
Same ID
Same Class
Same Text
Same Location
↓
Easy to Locate
Dynamic Element
↓
Changing ID
Changing Class
Changing Text
Changing Position
Delayed Appearance
DOM Replacement
↓
Requires Robust Handling
2. Why are Dynamic Elements Difficult in Selenium?
Selenium interacts with the DOM exposed by the browser. If an element is generated later, replaced after an AJAX request, or receives changing attributes, a locator that worked previously may not work in the same way during another execution.
Common problems include unstable locators, delayed element creation, stale element references, dynamic text, changing attributes, loading overlays, asynchronous requests, dynamic tables, autocomplete suggestions, and components that are re-rendered by modern JavaScript frameworks.
3. Static vs Dynamic Elements
| Static Element | Dynamic Element |
| Properties usually remain constant. | One or more properties can change. |
| Usually easier to locate. | May require flexible locators. |
| Often available immediately. | May appear after asynchronous processing. |
| Usually has predictable DOM structure. | DOM structure may change. |
| Simple synchronization may be sufficient. | Synchronization is often required. |
4. Example of a Static Element
<button id="loginButton">
Login
</button>
The ID remains the same, so a simple locator can be used.
driver.findElement(
By.id("loginButton")).click();
5. Example of a Dynamic Element
<button id="button_78291">
Login
</button>
On another execution, the ID might become:
<button id="button_91384">
Login
</button>
A locator based on the complete dynamic ID can therefore become unreliable.
6. Common Characteristics of Dynamic Elements
- Automatically generated IDs.
- Changing class names.
- Changing attributes.
- Changing text.
- Elements created after an AJAX request.
- Elements loaded after JavaScript execution.
- Elements that appear after a user action.
- Elements that disappear after processing.
- Elements replaced during DOM re-rendering.
- Dynamic tables and rows.
- Dynamic dropdown options.
- Autocomplete suggestions.
- Loading indicators.
- Dynamic popups and modals.
- Changing button states.
- Lazy-loaded content.
7. Main Challenges in Handling Dynamic Elements
| Challenge | Example | Common Approach |
| Changing ID | button_123 to button_456 | Partial attribute locator. |
| Changing class | item-active to item-selected | Stable class or attribute. |
| Delayed appearance | Search result appears later. | Explicit wait. |
| Dynamic text | Loading to Completed. | Text condition. |
| DOM replacement | React re-render. | Re-locate element. |
| Dynamic rows | AJAX table. | Wait for rows. |
| Dynamic dropdown | Options loaded after click. | Wait for option. |
| Overlay | Loading spinner. | Wait for invisibility. |
8. Dynamic IDs
One of the most common dynamic-element problems is an automatically generated ID.
<input id="user_12873" type="text">
The next execution may generate:
<input id="user_98432" type="text">
This locator is fragile:
driver.findElement(
By.id("user_12873"));
9. Handling Dynamic IDs with XPath contains()
If a stable portion of the ID remains constant, XPath contains() can be used.
driver.findElement(
By.xpath("//input[contains(@id,'user_')]"))
.sendKeys("admin");
This works when the changing part is different but the meaningful prefix remains stable.
10. Handling Dynamic IDs with starts-with()
driver.findElement(
By.xpath("//input[starts-with(@id,'user_')]"))
.sendKeys("admin");
starts-with() is useful when a stable prefix is available.
11. Handling Dynamic IDs with CSS Attribute Selectors
CSS selectors can also identify elements using partial attribute values.
driver.findElement(
By.cssSelector("input[id^='user_']"))
.sendKeys("admin");
The ^= CSS operator means that the attribute value starts with the specified text.
12. CSS contains Attribute Selector
driver.findElement(
By.cssSelector("input[id*='user_']"))
.sendKeys("admin");
The *= operator searches for an attribute value containing the specified text.
13. CSS ends-with Attribute Selector
driver.findElement(
By.cssSelector("input[id$='_field']"))
.sendKeys("admin");
The $= operator matches an attribute value ending with the specified text.
14. Dynamic Class Names
Some applications generate changing class names.
<button class="btn_x7a91 primary">
Login
</button>
Instead of depending on the unstable class, identify a stable attribute or class.
driver.findElement(
By.cssSelector("button.primary"))
.click();
15. Dynamic Text
Text can also change depending on application state.
<div id="status">Loading...</div>
Later:
<div id="status">Completed</div>
Use a stable locator for the element and synchronize with the expected text.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10));
wait.until(
ExpectedConditions.textToBePresentInElementLocated(
By.id("status"),
"Completed"));
16. Dynamic Attributes
Attributes such as class, value, aria-label, data-state, or custom data attributes may change during application execution.
<button id="submit" data-state="loading">
Submit
</button>
After processing:
<button id="submit" data-state="ready">
Submit
</button>
17. Waiting for Dynamic Attributes
wait.until(
ExpectedConditions.attributeToBe(
By.id("submit"),
"data-state",
"ready"));
18. Using attributeContains()
wait.until(
ExpectedConditions.attributeContains(
By.id("submit"),
"class",
"active"));
19. Dynamic Visibility
An element may initially exist in the DOM but become visible only after another operation.
<div id="result" style="display:none;">
Search Result
</div>
After the search:
<div id="result">
Search Result
</div>
20. Waiting for Dynamic Visibility
WebElement result = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("result")));
21. Dynamic Element Presence
Some elements do not exist in the DOM initially and are created later.
wait.until(
ExpectedConditions.presenceOfElementLocated(
By.id("dynamicElement")));
Presence checks that the element exists in the DOM. It should be used when DOM presence is the required condition rather than visual interaction.
22. Presence vs Visibility
| Condition | Meaning | Typical Use |
| Presence | Element exists in DOM. | DOM-level availability. |
| Visibility | Element is displayed. | Reading or interacting with visible content. |
| Clickable | Element is visible and enabled. | Click operation. |
23. Dynamic Enabled State
A button can be visible but disabled until the application completes validation.
<button id="submit" disabled>
Submit
</button>
After validation:
<button id="submit">
Submit
</button>
24. Handling Dynamic Enabled Buttons
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("submit"))).click();
This is generally preferable to checking the button once and immediately clicking it.
25. Dynamic Loading Spinner
Loading spinners are common in AJAX-based applications.
Search
↓
Spinner Appears
↓
API Request
↓
Response
↓
Results Render
↓
Spinner Disappears
26. Handling Loading Spinner
driver.findElement(
By.id("search")).click();
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.id("loader")));
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("results")));
27. Dynamic AJAX Content
AJAX allows web applications to communicate with the server without necessarily performing a complete page refresh. Content may therefore appear after Selenium has already continued executing.
Click Load Data
↓
AJAX Request
↓
Server Response
↓
DOM Update
↓
New Element Available
28. Handling AJAX Elements
driver.findElement(
By.id("loadData")).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("ajaxResult")));
29. Dynamic Dropdowns
Custom dropdowns frequently load their options dynamically after the dropdown is opened.
driver.findElement(
By.id("countryDropdown")).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//li[normalize-space()='India']")))
.click();
30. Static Select Dropdown vs Dynamic Dropdown
| Static Select | Dynamic Custom Dropdown |
| Usually uses HTML select. | Often uses div, ul, li, buttons, or custom components. |
| Can be handled with Select. | Often requires normal element interaction. |
| Options usually exist in the DOM. | Options may be generated dynamically. |
| Synchronization is often simpler. | May require explicit waits. |
31. Dynamic Autocomplete
Autocomplete controls typically send a request after the user types a few characters and then display suggestions.
driver.findElement(
By.id("city")).sendKeys("Mum");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.xpath("//li[contains(.,'Mumbai')]"))).click();
32. Handling Dynamic Search Suggestions
WebElement search = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("search")));
search.sendKeys("Selenium");
By suggestion = By.xpath(
"//li[contains(normalize-space(.),'Selenium WebDriver')]");
wait.until(
ExpectedConditions.elementToBeClickable(
suggestion)).click();
33. Dynamic Tables
Dynamic tables may load rows from an API. The number of rows, cell values, pagination, and sorting order may change during runtime.
<table id="users">
<tbody>
<tr>
<td>Manish</td>
<td>QA</td>
</tr>
</tbody>
</table>
34. Waiting for Dynamic Table Rows
List<WebElement> rows = wait.until(
ExpectedConditions.visibilityOfAllElementsLocatedBy(
By.cssSelector("#users tbody tr")));
35. Finding a Dynamic Table Row
By row = By.xpath(
"//table[@id='users']//tr[td[normalize-space()='Manish']]");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
row));
36. Dynamic Pagination
When pagination is used, clicking the next-page button may trigger an asynchronous update.
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("nextPage"))).click();
wait.until(
ExpectedConditions.visibilityOfAllElementsLocatedBy(
By.cssSelector("table tbody tr")));
37. Dynamic Search Results
driver.findElement(
By.id("searchBox")).sendKeys("Selenium");
driver.findElement(
By.id("searchButton")).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".search-result")));
38. Dynamic Modal
A modal can be created only after the user clicks a button.
driver.findElement(
By.id("openModal")).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("modal")));
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("confirm"))).click();
39. Dynamic Toast Messages
Toast notifications often appear for only a short period.
driver.findElement(
By.id("save")).click();
String message = wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".toast")))
.getText();
System.out.println(message);
40. Waiting for Toast Text
wait.until(
ExpectedConditions.textToBePresentInElementLocated(
By.cssSelector(".toast"),
"Saved successfully"));
41. Dynamic Checkboxes
A checkbox can be dynamically generated or its selection state can change after another operation.
By checkbox = By.id("terms");
wait.until(
ExpectedConditions.elementToBeClickable(
checkbox)).click();
wait.until(
ExpectedConditions.elementToBeSelected(
checkbox));
42. Dynamic Radio Buttons
By radio = By.id("premium");
wait.until(
ExpectedConditions.elementToBeClickable(
radio)).click();
wait.until(
ExpectedConditions.elementToBeSelected(
radio));
43. Dynamic File Upload Control
When the file input is present dynamically, wait for the input before using sendKeys().
By fileInput = By.cssSelector(
"input[type='file']");
wait.until(
ExpectedConditions.presenceOfElementLocated(
fileInput))
.sendKeys("C:\\files\\document.pdf");
44. Dynamic Iframes
An iframe may become available only after the application finishes loading or after a user action.
wait.until(
ExpectedConditions.frameToBeAvailableAndSwitchToIt(
By.id("paymentFrame")));
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("cardNumber")));
45. Dynamic Alerts
JavaScript alerts may appear after asynchronous processing.
driver.findElement(
By.id("delete")).click();
Alert alert = wait.until(
ExpectedConditions.alertIsPresent());
alert.accept();
46. Dynamic Windows and Tabs
A new tab or window can be opened after an action and may not be immediately available.
String parent = driver.getWindowHandle();
driver.findElement(
By.id("openWindow")).click();
wait.until(
ExpectedConditions.numberOfWindowsToBe(2));
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(parent)) {
driver.switchTo().window(handle);
break;
}
}
47. Dynamic URLs
After an action, an application may navigate asynchronously to a URL containing dynamic path or query parameters.
driver.findElement(
By.id("profile")).click();
wait.until(
ExpectedConditions.urlContains(
"/profile"));
48. Dynamic Page Titles
wait.until(
ExpectedConditions.titleContains(
"Dashboard"));
49. Dynamic React Components
React applications can re-render components when their state or props change. A WebElement reference captured before the re-render can become stale.
By button = By.id("dynamicButton");
driver.findElement(
By.id("update")).click();
wait.until(
ExpectedConditions.elementToBeClickable(
button)).click();
50. Dynamic Angular Components
Angular applications can update component content after asynchronous operations and state changes.
driver.findElement(
By.id("load")).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("angularResult")));
51. Dynamic Vue Components
Vue applications use reactive updates that can change DOM content during runtime.
driver.findElement(
By.id("load")).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector("[data-testid='result']")));
52. StaleElementReferenceException
One of the most important problems with dynamic elements is StaleElementReferenceException. It occurs when the previously located element is no longer attached to the current DOM.
WebElement element = driver.findElement(
By.id("result"));
driver.findElement(
By.id("refresh")).click();
element.click();
The refresh or re-render can replace the original DOM node.
53. Handling Stale Elements
Instead of storing an old WebElement and using it after a DOM update, store the locator and locate the current element again.
By result = By.id("result");
driver.findElement(
By.id("refresh")).click();
wait.until(
ExpectedConditions.elementToBeClickable(
result)).click();
54. Waiting for Staleness
WebElement oldElement = driver.findElement(
By.id("result"));
driver.findElement(
By.id("refresh")).click();
wait.until(
ExpectedConditions.stalenessOf(
oldElement));
55. Dynamic Element with Changing Position
Elements can move because of sorting, filtering, responsive layouts, animations, or dynamically inserted content. Avoid relying on screen coordinates as a primary locator.
Wrong approach:
Click at fixed screen coordinate
Better approach:
Locate the element using stable DOM attributes
and synchronize with its required state.
56. Dynamic Elements with Changing Text
If only part of the text is stable, use a partial text strategy.
driver.findElement(
By.xpath("//button[contains(normalize-space(.),'Order')]"))
.click();
57. normalize-space() for Dynamic Text
normalize-space() is useful when whitespace around the text is inconsistent.
driver.findElement(
By.xpath(
"//button[normalize-space()='Submit Order']"))
.click();
58. Combining Dynamic XPath Conditions
Multiple stable conditions can make a locator more reliable.
driver.findElement(
By.xpath(
"//button[contains(@class,'primary') and contains(normalize-space(.),'Submit')]"))
.click();
59. Parent-Child Relationship for Dynamic Elements
When several similar elements exist, locate a stable parent first and then identify the required child.
driver.findElement(
By.xpath(
"//div[@data-product='selenium']//button[contains(.,'Add to Cart')]"))
.click();
60. Descendant Strategy
driver.findElement(
By.xpath(
"//div[@id='productCard']//button"))
.click();
This can be useful when the child element has unstable attributes but its parent has a stable identifier.
61. Dynamic E-Commerce Product Cards
<div class="product-card" data-product-id="101">
<h3>Selenium Course</h3>
<button>Add to Cart</button>
</div>
driver.findElement(
By.xpath(
"//div[@data-product-id='101']//button[normalize-space()='Add to Cart']"))
.click();
62. Dynamic Login Example
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10));
By username = By.id("username");
By password = By.id("password");
By login = By.id("login");
By dashboard = By.id("dashboard");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
username)).sendKeys("admin");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
password)).sendKeys("admin123");
wait.until(
ExpectedConditions.elementToBeClickable(
login)).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
dashboard));
63. Dynamic Search Example
By searchBox = By.id("search");
By searchButton = By.id("searchButton");
By result = By.cssSelector(".search-result");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
searchBox)).sendKeys("Selenium");
wait.until(
ExpectedConditions.elementToBeClickable(
searchButton)).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
result));
64. Dynamic Registration Example
By username = By.id("username");
By email = By.id("email");
By password = By.id("password");
By register = By.id("register");
By success = By.id("successMessage");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
username)).sendKeys("testuser");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
email)).sendKeys("[email protected]");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
password)).sendKeys("Password123");
wait.until(
ExpectedConditions.elementToBeClickable(
register)).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
success));
65. Dynamic E-Commerce Cart Example
By addToCart = By.xpath(
"//div[@data-product='101']//button[contains(.,'Add to Cart')]");
By cart = By.id("cart");
By checkout = By.id("checkout");
wait.until(
ExpectedConditions.elementToBeClickable(
addToCart)).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
cart));
wait.until(
ExpectedConditions.elementToBeClickable(
checkout)).click();
66. Dynamic Table Example
By tableRows = By.cssSelector(
"#users tbody tr");
List<WebElement> rows = wait.until(
ExpectedConditions.visibilityOfAllElementsLocatedBy(
tableRows));
for (WebElement row : rows) {
System.out.println(row.getText());
}
67. Dynamic Table Row by Text
By userRow = By.xpath(
"//table[@id='users']//tr[td[normalize-space()='Manish']]");
WebElement row = wait.until(
ExpectedConditions.visibilityOfElementLocated(
userRow));
System.out.println(row.getText());
68. Dynamic Loading Flow
Test Starts
↓
Page Loads
↓
Dynamic Component Created
↓
API Request
↓
Loader Displayed
↓
Response Received
↓
DOM Updated
↓
Loader Hidden
↓
Element Becomes Interactive
↓
Selenium Performs Action
69. Implicit Wait for Dynamic Elements
Implicit Wait tells WebDriver how long to wait when locating elements before reporting that the lookup failed. It is a general lookup mechanism rather than a replacement for condition-specific synchronization.
driver.manage().timeouts().implicitlyWait(
Duration.ofSeconds(10));
70. Explicit Wait for Dynamic Elements
Explicit Wait is generally more suitable when the test needs to wait for a particular state of a dynamic element.
WebDriverWait wait = new WebDriverWait(
driver,
Duration.ofSeconds(10));
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("dynamicElement")));
71. FluentWait for Dynamic Elements
FluentWait allows timeout and polling behavior to be configured for a wait.
Wait<WebDriver> fluentWait =
new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(15))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class);
WebElement element = fluentWait.until(
driver -> driver.findElement(
By.id("dynamicElement")));
72. Polling Concept
Wait Starts
↓
Check Condition
↓
Condition False
↓
Wait for Polling Interval
↓
Check Again
↓
Condition True?
├── Yes → Continue
└── No → Repeat Until Timeout
73. Handling Dynamic Elements with WebDriverWait
public class DynamicElementHelper {
private WebDriver driver;
private WebDriverWait wait;
public DynamicElementHelper(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(
driver,
Duration.ofSeconds(10));
}
public WebElement waitForVisible(By locator) {
return wait.until(
ExpectedConditions.visibilityOfElementLocated(
locator));
}
public WebElement waitForClickable(By locator) {
return wait.until(
ExpectedConditions.elementToBeClickable(
locator));
}
public void waitForInvisible(By locator) {
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
locator));
}
}
74. Handling Dynamic Elements with Page Object Model
Synchronization can be placed inside Page Object methods so that tests remain clean and reusable.
public class LoginPage {
private WebDriver driver;
private WebDriverWait wait;
private By username = By.id("username");
private By password = By.id("password");
private By login = By.id("login");
private By dashboard = By.id("dashboard");
public LoginPage(WebDriver driver) {
this.driver = driver;
this.wait = new WebDriverWait(
driver,
Duration.ofSeconds(10));
}
public void login(String user, String pass) {
wait.until(
ExpectedConditions.visibilityOfElementLocated(
username)).sendKeys(user);
wait.until(
ExpectedConditions.visibilityOfElementLocated(
password)).sendKeys(pass);
wait.until(
ExpectedConditions.elementToBeClickable(
login)).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
dashboard));
}
}
75. Why Page Object Model Helps Dynamic Elements
- Locators are centralized.
- Wait logic can be centralized.
- Dynamic-element handling becomes reusable.
- Test cases become easier to read.
- Locator changes can be made in one location.
- Synchronization logic is separated from test scenarios.
76. Handling Dynamic Elements with Stable Attributes
Modern applications sometimes provide attributes specifically useful for automation, such as data-testid, data-test, or other stable identifiers.
<button data-testid="login-button">
Login
</button>
driver.findElement(
By.cssSelector(
"[data-testid='login-button']"))
.click();
77. Why Stable Test Attributes Are Useful
| Locator | Typical Stability | Comment |
| Stable ID | High | Good when intentionally designed for the element. |
| data-testid | High | Useful dedicated test attribute. |
| Stable name | High | Useful for form controls. |
| Stable CSS | Medium to High | Depends on application structure. |
| Relative XPath | Medium | Can be robust when based on stable relationships. |
| Absolute XPath | Low | Fragile when DOM structure changes. |
| Random generated class | Low | Often changes between builds or renders. |
78. Avoid Absolute XPath for Dynamic Elements
/html/body/div[2]/div[1]/div[3]/button
This XPath depends heavily on the exact DOM hierarchy. If a container is added or removed, the XPath may stop working.
79. Prefer Relative XPath
//button[@data-testid='login-button']
Relative XPath can focus on stable attributes and relationships instead of the complete document structure.
80. Dynamic Elements and XPath contains()
//button[contains(@id,'submit_')]
81. Dynamic Elements and XPath starts-with()
//input[starts-with(@id,'user_')]
82. Dynamic Elements and XPath text()
//button[text()='Login']
When the text itself is dynamic, partial matching can be more appropriate.
//button[contains(text(),'Login')]
83. Dynamic Elements and normalize-space()
//button[normalize-space()='Login']
This is useful when extra whitespace may be present in the element's text.
84. Combining XPath Conditions
//button[
contains(@class,'primary')
and contains(normalize-space(.),'Submit')
]
Combining stable conditions can reduce the chance of selecting the wrong element when several similar elements exist.
85. Dynamic Elements with Parent Relationships
//div[@data-product='101']//button[contains(.,'Buy')]
This approach identifies the target button in the context of a known product container.
86. Dynamic Elements with Sibling Relationships
//label[normalize-space()='Email']
/following-sibling::input
Relationships can be useful when the input itself has an unstable attribute but its associated label is stable.
87. Dynamic Elements with Following Relationship
//span[normalize-space()='Username']
/following::input[1]
Use relationship-based XPath carefully and keep the locator as specific as possible.
88. Dynamic Elements in Forms
Form elements can become available or enabled after validation.
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("email")))
.sendKeys("[email protected]");
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("submit"))).click();
89. Dynamic Validation Messages
driver.findElement(
By.id("email")).sendKeys("invalid");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".validation-error")));
90. Dynamic Success Messages
driver.findElement(
By.id("save")).click();
wait.until(
ExpectedConditions.textToBePresentInElementLocated(
By.cssSelector(".success-message"),
"Saved successfully"));
91. Dynamic Notification Badge
Notification counts may change after an asynchronous operation.
driver.findElement(
By.id("markAsRead")).click();
wait.until(
ExpectedConditions.attributeToBe(
By.id("notificationBadge"),
"data-count",
"0"));
92. Dynamic Cart Count
driver.findElement(
By.id("addToCart")).click();
wait.until(
ExpectedConditions.textToBePresentInElementLocated(
By.id("cartCount"),
"1"));
93. Dynamic Price Update
Product prices can change after selecting quantity, size, color, coupon, shipping method, or other options.
driver.findElement(
By.id("quantity")).sendKeys("2");
wait.until(
ExpectedConditions.textToBePresentInElementLocated(
By.id("totalPrice"),
"2000"));
94. Dynamic Filter Results
driver.findElement(
By.id("category")).click();
wait.until(
ExpectedConditions.elementToBeClickable(
By.xpath("//option[contains(.,'Laptop')]")))
.click();
wait.until(
ExpectedConditions.visibilityOfAllElementsLocatedBy(
By.cssSelector(".product-card")));
95. Dynamic Sorting
driver.findElement(
By.id("sort")).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".sorted-results")));
96. Dynamic Infinite Scroll
Infinite-scroll applications load additional content as the user reaches the bottom of the page.
JavascriptExecutor js =
(JavascriptExecutor) driver;
js.executeScript(
"window.scrollTo(0, document.body.scrollHeight);");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.cssSelector(".new-results")));
97. Dynamic Lazy Loading
By image = By.cssSelector(
"[data-testid='product-image']");
WebElement element = wait.until(
ExpectedConditions.presenceOfElementLocated(
image));
JavascriptExecutor js =
(JavascriptExecutor) driver;
js.executeScript(
"arguments[0].scrollIntoView(true);",
element);
wait.until(
ExpectedConditions.visibilityOfElementLocated(
image));
98. Dynamic Overlay Handling
By overlay = By.cssSelector(
".loading-overlay");
By button = By.id("continue");
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
overlay));
wait.until(
ExpectedConditions.elementToBeClickable(
button)).click();
99. Dynamic Element Retry Strategy
When a component can be replaced during a short interaction window, it can be useful to re-locate the element rather than holding a potentially stale reference.
By button = By.id("dynamicButton");
for (int i = 0; i < 3; i++) {
try {
wait.until(
ExpectedConditions.elementToBeClickable(
button)).click();
break;
} catch (StaleElementReferenceException e) {
if (i == 2) {
throw e;
}
}
}
100. Dynamic Element Handling Strategy
Identify Element
↓
Check Whether Locator Is Stable
↓
Identify Dynamic Property
↓
Select Stable Attribute or Relationship
↓
Determine Required State
↓
Choose Appropriate Wait
↓
Locate Current Element
↓
Perform Action
↓
Validate Result
101. Common Mistake: Using Fixed Sleep Everywhere
Thread.sleep(5000);
driver.findElement(
By.id("result")).click();
A fixed sleep does not verify that the required condition has actually occurred.
102. Better Approach
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("result"))).click();
103. Common Mistake: Waiting for the Wrong Element
wait.until(
ExpectedConditions.visibilityOfElementLocated(
By.id("header")));
driver.findElement(
By.id("dynamicButton")).click();
The header being visible does not prove that the dynamic button is ready.
104. Better Approach: Wait for the Required Element
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("dynamicButton"))).click();
105. Common Mistake: Increasing Timeout Without Investigation
If a dynamic element fails to appear, do not immediately increase the timeout. First verify the locator, frame, window, application state, network behavior, overlay, and whether the expected element should actually exist.
106. Common Mistake: Assuming Presence Means Clickable
WebElement element = wait.until(
ExpectedConditions.presenceOfElementLocated(
By.id("submit")));
element.click();
Presence alone does not guarantee that the element is displayed and enabled.
107. Better Approach for Click Operations
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("submit"))).click();
108. Common Mistake: Holding WebElement References Too Long
Long-lived WebElement references are more vulnerable to becoming stale when the application frequently re-renders its DOM.
WebElement element =
driver.findElement(By.id("dynamic"));
performSeveralOperations();
element.click();
109. Better Approach: Store Locators
By dynamicElement = By.id("dynamic");
wait.until(
ExpectedConditions.elementToBeClickable(
dynamicElement)).click();
110. Common Mistake: Using Random Dynamic Attributes
By.id("generated_987654321")
Such locators are likely to fail when the generated value changes.
111. Better Approach: Identify the Stable Portion
By.xpath(
"//input[starts-with(@id,'generated_')]")
112. Common Mistake: Overusing XPath Indexes
(//button)[7]
If another button is inserted before the target, the index may point to a different element.
113. Better Approach: Use Meaningful Relationships
//div[@data-product='101']//button[
normalize-space()='Add to Cart'
]
114. Common Mistake: Ignoring Loading Overlays
A button may be visible but a transparent or visible overlay can intercept the click.
wait.until(
ExpectedConditions.invisibilityOfElementLocated(
By.cssSelector(".loading-overlay")));
wait.until(
ExpectedConditions.elementToBeClickable(
By.id("submit"))).click();
115. Common Mistake: Ignoring DOM Re-Rendering
Frameworks such as React, Angular, and Vue can replace DOM nodes during state updates. Reusing an old WebElement after such an update can result in stale-element failures.
116. Common Mistake: Using JavaScript Click as the First Solution
JavascriptExecutor js =
(JavascriptExecutor) driver;
js.executeScript(
"arguments[0].click();",
element);
JavaScript execution can sometimes bypass normal interaction behavior, but it should not automatically be used to hide synchronization or application-state problems. First make sure the element is in the correct state and that normal WebDriver interaction is appropriate.
117. Debugging Dynamic Element Failures
Test Failure
↓
Check Exception
↓
Check Locator
↓
Check Element DOM
↓
Check Dynamic Attribute
↓
Check Visibility
↓
Check Enabled State
↓
Check Overlay
↓
Check Frame
↓
Check Window
↓
Check DOM Re-render
↓
Choose Correct Synchronization
118. Dynamic Element Debugging Checklist
- Inspect the element in browser DevTools.
- Check whether its ID changes.
- Check whether its class changes.
- Check whether its text changes.
- Check whether the element is initially present.
- Check whether it appears after an API request.
- Check whether a loader blocks it.
- Check whether the element is inside an iframe.
- Check whether the element is inside another window or tab.
- Check whether the DOM is re-rendered.
- Check whether the locator selects multiple elements.
- Check whether the locator remains stable across executions.
- Choose the correct ExpectedCondition.
119. Dynamic Element Handling in a Real Test Flow
Open Application
↓
Wait for Login Form
↓
Enter Credentials
↓
Click Login
↓
Wait for Loader to Disappear
↓
Wait for Dashboard
↓
Search Product
↓
Wait for Suggestions
↓
Select Product
↓
Wait for Product Details
↓
Add Product
↓
Wait for Cart Update
↓
Open Cart
↓
Wait for Checkout
↓
Complete Checkout
↓
Wait for Confirmation
↓
Validate Result
120. Practical Project: Dynamic E-Commerce Application
A practical dynamic-element automation project can include product search, autocomplete suggestions, product cards, dynamic prices, add-to-cart operations, cart updates, checkout, loading overlays, and order confirmation.
public class EcommerceTest {
WebDriver driver;
WebDriverWait wait;
@Test
public void dynamicElementTest() {
By search = By.id("search");
By suggestion = By.xpath(
"//li[contains(.,'Selenium')]");
By product = By.xpath(
"//div[@data-product='101']//button[contains(.,'Add to Cart')]");
By cart = By.id("cart");
By checkout = By.id("checkout");
By confirmation = By.id("orderConfirmation");
wait.until(
ExpectedConditions.visibilityOfElementLocated(
search)).sendKeys("Selenium");
wait.until(
ExpectedConditions.elementToBeClickable(
suggestion)).click();
wait.until(
ExpectedConditions.elementToBeClickable(
product)).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
cart));
wait.until(
ExpectedConditions.elementToBeClickable(
checkout)).click();
wait.until(
ExpectedConditions.visibilityOfElementLocated(
confirmation));
}
}
121. Recommended Dynamic Element Handling Techniques
| Technique | Purpose |
| Stable ID | Locate elements with a consistent identifier. |
| data-testid | Use dedicated stable test attributes. |
| contains() | Handle partial dynamic attribute values. |
| starts-with() | Handle stable attribute prefixes. |
| normalize-space() | Handle inconsistent text whitespace. |
| Parent-child relationship | Locate elements within a stable container. |
| Explicit Wait | Wait for a specific application condition. |
| FluentWait | Customize timeout and polling behavior. |
| Re-location | Handle DOM replacement and stale references. |
| Loader synchronization | Prevent overlays from blocking interactions. |
| Page Object Model | Centralize locators and synchronization. |
122. Dynamic Element Handling Best Practices
- Prefer stable locators over generated attributes.
- Use dedicated test attributes when available.
- Use relative XPath instead of fragile absolute XPath.
- Use CSS selectors when they provide a clear stable locator.
- Wait for the exact state required by the next action.
- Use explicit waits for asynchronous UI behavior.
- Wait for overlays to disappear before interacting.
- Re-locate elements after DOM replacement.
- Keep dynamic-element logic inside Page Objects or reusable utilities.
- Avoid unnecessary Thread.sleep() calls.
- Do not solve every failure by increasing the timeout.
- Verify that the locator is correct before diagnosing synchronization.
- Keep synchronization logic readable and maintainable.
- Use meaningful application states for synchronization.
- Validate the final state after important dynamic operations.
123. Dynamic Element Handling Do's and Don'ts
| Do | Don't |
| Use stable attributes. | Depend on random generated IDs. |
| Use explicit waits for dynamic states. | Use Thread.sleep() everywhere. |
| Re-locate after DOM replacement. | Reuse stale WebElement references. |
| Wait for overlays to disappear. | Ignore loading layers. |
| Use meaningful XPath relationships. | Overuse absolute XPath. |
| Verify application state. | Assume element presence means readiness. |
| Centralize wait utilities. | Duplicate synchronization logic everywhere. |
| Investigate failures. | Increase timeout blindly. |
124. Interview Questions: What is a Dynamic Element?
Answer: A dynamic element is a web element whose properties, content, availability, position, or DOM representation can change during application execution.
125. Interview Questions: Why are Dynamic Elements Difficult to Automate?
Answer: Their attributes or DOM representation can change, and they may appear only after asynchronous operations. A static locator or immediate Selenium action may therefore become unreliable.
126. Interview Questions: How Do You Handle Dynamic IDs?
Answer: Identify the stable portion of the attribute and use a flexible locator such as XPath contains(), XPath starts-with(), or CSS attribute selectors. Prefer a stable dedicated attribute when available.
127. Interview Questions: How Do You Handle Elements Loaded Through AJAX?
Answer: Wait for an observable application condition such as the target element becoming visible, a loading indicator disappearing, expected text appearing, or a relevant attribute changing.
128. Interview Questions: How Do You Handle Stale Dynamic Elements?
Answer: Re-locate the element after the DOM update rather than continuing to use the old WebElement reference. A wait for the new element state can be used when appropriate.
129. Interview Questions: Which Wait is Commonly Used for Dynamic Elements?
Answer: Explicit Wait is commonly used because it allows the test to wait for a specific condition such as presence, visibility, clickability, text, attribute state, alert, frame, or window availability. FluentWait can be used when customized polling behavior is needed.
130. Interview Questions: What is the Difference Between Presence and Visibility?
Answer: Presence means the element exists in the DOM, while visibility means the element satisfies WebDriver's displayedness requirements. A present element may still be hidden.
131. Interview Questions: How Do You Handle Dynamic Dropdowns?
Answer: Open the dropdown, wait for the required option to become available or clickable, and then select the option using a stable locator.
132. Interview Questions: How Do You Handle Dynamic Tables?
Answer: Wait for the table rows or required data to become available and then locate the desired row using stable attributes, cell text, or relationships within the table.
133. Interview Questions: How Do You Handle Dynamic Buttons?
Answer: Use a stable locator and wait until the button reaches the required state, commonly with elementToBeClickable() when the action requires the button to be visible and enabled.
134. Interview Questions: Can Thread.sleep() Handle Dynamic Elements?
Answer: Thread.sleep() can delay execution, but it is a fixed delay and does not verify whether the dynamic element has reached the required state. Condition-based waits are generally more suitable.
135. Interview Questions: Can XPath Solve All Dynamic Element Problems?
Answer: No. XPath can help create flexible locators, but it does not solve timing or synchronization problems. Dynamic-element handling usually requires both a stable locator strategy and appropriate synchronization.
136. Interview Questions: Can Explicit Wait Fix an Incorrect Locator?
Answer: No. An explicit wait can handle timing, but it cannot correct a locator that identifies the wrong element or no element at all.
137. Interview Questions: How Do You Handle Dynamic Loading Spinners?
Answer: Wait for the spinner or overlay to become invisible and then wait for the required content or control to become available.
138. Interview Questions: How Do You Handle Dynamic Modals?
Answer: Trigger the modal, wait for its container to become visible, and then wait for the required modal control to become clickable before interacting with it.
139. Interview Questions: How Do You Handle Dynamic React Components?
Answer: Use stable locators, wait for the required state, and re-locate elements after React re-renders the component when necessary to avoid stale references.
140. Interview Questions: How Do You Make Dynamic Element Automation Reliable?
Answer: Use stable locators, condition-based synchronization, appropriate wait strategies, re-location after DOM changes, reusable wait utilities, Page Object Model, and meaningful application-state validation.
141. Dynamic Element Handling Checklist
- Identify whether the element is actually dynamic.
- Inspect the DOM in browser DevTools.
- Find stable attributes.
- Check whether IDs are generated dynamically.
- Check whether classes are generated dynamically.
- Check whether text changes.
- Check whether the element appears after an AJAX request.
- Check whether the element is initially hidden.
- Check whether the element becomes enabled later.
- Check for loading overlays.
- Check whether the DOM is re-rendered.
- Use relative XPath where appropriate.
- Use CSS selectors where appropriate.
- Use contains() or starts-with() for suitable dynamic attributes.
- Use normalize-space() for inconsistent text.
- Use parent-child relationships for repeated elements.
- Use explicit waits for dynamic states.
- Use FluentWait when custom polling is required.
- Re-locate elements after DOM replacement.
- Avoid unnecessary Thread.sleep().
- Keep timeout values reasonable.
- Centralize synchronization in reusable methods.
- Use Page Object Model for maintainability.
- Validate the final application state.
142. Final Summary
Handling Dynamic Elements is a fundamental Selenium WebDriver skill for automating modern web applications. Dynamic elements can change their IDs, classes, attributes, text, visibility, enabled state, position, DOM representation, or availability during runtime.
Reliable dynamic-element automation requires two major strategies: creating stable locators and synchronizing with the correct application state. XPath functions such as contains(), starts-with(), and normalize-space(), CSS attribute selectors, stable test attributes, and parent-child relationships can help locate changing elements.
Synchronization techniques such as explicit waits, FluentWait, visibility checks, clickability checks, text conditions, attribute conditions, staleness checks, frame waits, window waits, and loader synchronization help Selenium interact with elements at the appropriate time.
The most important principle is to avoid treating dynamic-element failures as simple timing problems. First identify the reason the element is dynamic, choose a stable locator, determine the required application state, use the appropriate synchronization condition, and re-locate the element when the DOM has been replaced.
143. Selenium Training Resources
Learn Selenium WebDriver, Java automation, locators, dynamic elements, waits, synchronization, TestNG, Page Object Model, automation frameworks, and practical automation testing through the Selenium Training Course.
For a course demonstration, visit the Selenium Course Demo.